#include "global.h"
#include <EIKENV.H>
#include <EIKAPPUI.H>
#include "UIControlDes.h"
#include <COEUTILS.H>
#include <aknutils.h>

UIControlEnv* UIControlEnv::iStatic = NULL;

UIControlEnv::UIControlEnv() : iSearchPaths(NULL)
{

}

UIControlEnv::~UIControlEnv()
{
	delete iSearchPaths;
	
	for(TUint i=0;i<sizeof(iHelperBitmap)/sizeof(CWritableBitmap*);i++)
		delete iHelperBitmap[i];
}

UIControlEnv* UIControlEnv::NewL()
{
	UIControlEnv* self = UIControlEnv::NewLC();
	CleanupStack::Pop(self);
	
	return self;
}

UIControlEnv* UIControlEnv::NewLC()
{
	UIControlEnv* self = new(ELeave) UIControlEnv;
	CleanupStack::PushL(self);
	
	self->ConstructL();
	
	return self;
}

void UIControlEnv::ConstructL()
	{
	iSearchPaths = new CDesCArrayFlat(5);
    TFileName temp;
    
    CEikonEnv::Static()->FsSession().PrivatePath(temp);
	temp.Insert(0, _L("c:"));
	iSearchPaths->AppendL(temp);
	temp[0] = 'e';
	iSearchPaths->AppendL(temp);
    
    _LIT(KTemp, "1.txt");
	temp.Copy(KTemp);
	CompleteWithAppPath(temp);
	temp.SetLength(temp.Length()-5);
	temp[0] = 'c';
	iSearchPaths->AppendL(temp);
	temp[0] = 'e';
	iSearchPaths->AppendL(temp);
	
	_LIT(KTemp2,"\\resource\\apps\\");
	temp.Copy(KTemp2);
	CompleteWithAppPath(temp);
	iSearchPaths->AppendL(temp);
	}


TRect UIControlEnv::GetClientRect()
{
	return CEikonEnv::Static()->EikAppUi()->ClientRect();
}

TDisplayMode UIControlEnv::GetDisplayMode()
{
	return CEikonEnv::Static()->ScreenDevice()->DisplayMode();
}

TBool UIControlEnv::ResolvePath(TDes& aPath) const
{
	if(aPath.Locate(':')!=KErrNotFound)
		return ConeUtils::FileExists(aPath);
	
	TFileName fileName;
	for(TInt i=0;i<Static()->iSearchPaths->Count();i++) 
	{
		fileName.Zero();
		fileName.Append((*Static()->iSearchPaths)[i]);
		fileName.Append(aPath);
		UIControlUtil::StringReplace(fileName, '/', '\\');
		
		if(ConeUtils::FileExists(fileName)) 
		{
			aPath.Copy(fileName);
			return ETrue;
		}
	}
	
	return EFalse;
}

CWritableBitmap* UIControlEnv::HelperBitmap(TInt aIndex, const TSize& aSize) 
{
	if(!iHelperBitmap[aIndex] 
	    || iHelperBitmap[aIndex]->SizeInPixels().iWidth<aSize.iWidth
	    || iHelperBitmap[aIndex]->SizeInPixels().iHeight<aSize.iHeight) 
	{
		delete iHelperBitmap[aIndex];
		iHelperBitmap[aIndex] = NULL;
		
		iHelperBitmap[aIndex] = CWritableBitmap::NewL(aSize, aIndex==0?EGray2:(aIndex==1?EGray256:EColor16M));
	}

	return iHelperBitmap[aIndex];
}

RFs& UIControlEnv::FsSession() const
{
	return CEikonEnv::Static()->FsSession();
}
HBufC* UIControlUtil::StringReplaceL(const TDesC& aSource, const TDesC& aTarget, const TDesC& aReplacement)
{
	HBufC* ret = HBufC::NewL(aSource.Length());
	TPtr dest = ret->Des();
	TInt pos1 = 0, pos2 = 0;
	do
	{
		pos2 = aSource.Mid(pos1).Find(aTarget);
		if(pos2==KErrNotFound)
		{
			TInt wantLength = aSource.Mid(pos1).Length();
			if(dest.Length() + wantLength > dest.MaxLength()) 
			{
				TInt length = dest.Length();
				ret = ret->ReAllocL(length + wantLength + 50);
				dest.Set(ret->Des());
				dest.SetLength(length);
			}
		
			dest.Append(aSource.Mid(pos1));
			break;
		}
		
		TInt wantLength = aSource.Mid(pos1, pos2).Length() + aReplacement.Length();
		if(dest.Length() + wantLength > dest.MaxLength()) 
		{
			TInt length = dest.Length();
			ret = ret->ReAllocL(length + wantLength + 50);
			dest.Set(ret->Des());
			dest.SetLength(length);
		}
		
		dest.Append(aSource.Mid(pos1, pos2));
		dest.Append(aReplacement);
		pos1 = pos1 + pos2 + aTarget.Length();
	}while(ETrue);
	
	return ret;
}


TBool UIControlUtil::StringSplit(const TDesC& aSource, TInt& aOffset, TChar aSeperator, TPtrC& aRet)
	{
		if(aOffset==KErrNotFound || aOffset >= aSource.Length()) 
			return EFalse;

		do 
		{
			TInt pos = aSource.Mid(aOffset).Locate(aSeperator);
			if(pos==KErrNotFound) 
			{
				aRet.Set(aSource.Mid(aOffset));
				aOffset = aSource.Length();
				return ETrue;
			}
			
			if(pos!=0) 
			{
				aRet.Set(aSource.Mid(aOffset, pos));
				aOffset += pos + 1;
				return ETrue;
			}
			aOffset++;
		}
		while(aOffset<aSource.Length());
		
		return EFalse;
	}

TUint32 UIControlUtil::StrToInt(const TDesC& aSource, TRadix aRadix)
{
	_LIT(KHexPrefix, "0x");
	_LIT(KTrue, "true");
	_LIT(KFalse, "false");
	
	if(aSource.CompareF(KTrue)==0)
		return 1;
	else if(aSource.CompareF(KFalse)==0)
		return 0;
	else if(aSource.Left(2).CompareF(KHexPrefix)==0)
	{
		TLex lex = aSource.Mid(2);
		TUint32 ret = 0;
		lex.Val(ret, EHex);
		
		return ret;	
	}
	else if(aRadix==EHex)
	{
		TLex lex = aSource;
		TUint32 ret = 0;
		lex.Val(ret, EHex);
		
		return ret;		
	}
	else 
	{
		TLex lex = aSource;
		TInt ret = 0;
		lex.Val(ret);
		
		return ret;	
	}
}

TBool UIControlUtil::StrToBool(const TDesC& aSource) 
{
	_LIT(K1, "1");
	_LIT(KTrue, "true");
	
	return aSource.Length()==0 || aSource.CompareF(KTrue)==0 || aSource.CompareF(K1)==0;
}

void UIControlUtil::Trim(TPtrC& aDest)
{
	TInt start = 0;
	while(start<aDest.Length()) 
	{
		TChar c = aDest[start];
		if(!c.IsSpace())
			break;
		
		start++;
	}
	
	if(start>=aDest.Length()) 
	{
		aDest.Set(KNullDesC);
		return;
	}
	
	TInt end = aDest.Length()-1;
	while(end>=0) 
	{
		TChar c = aDest[end];
		if(!c.IsSpace())
			break;
		
		end--;
	}
	
	aDest.Set(aDest.Mid(start, end-start+1));
}

void UIControlUtil::ParseHexColor(const TDesC& aSource, TRgb& aRgb)
{
	TBuf<6> s;
	if(aSource.Left(1) == _L("#"))
		s.Copy(aSource.Mid(1,6));
	else
		s.Copy(aSource.Mid(0,6));
		
	for(TInt i=s.Length();i<6;i++)
		s.Append('0');
	aRgb.SetRed(StrToInt(s.Mid(0,2), EHex));
	aRgb.SetGreen(StrToInt(s.Mid(2,2), EHex));
	aRgb.SetBlue(StrToInt(s.Mid(4,2), EHex));
	
	if(aSource.Length()>=8)
	{
		TUint32 alpha = StrToInt(aSource.Right(2), EHex);
		aRgb.SetAlpha(alpha);
	}
}

void UIControlUtil::ParseColor(const TDesC& aSource, TRgb& aRgb)
{
	if(aSource.Left(1).Compare(_L("#"))==0)
		ParseHexColor(aSource.Mid(1), aRgb);
	else 
	{
		if(aSource.CompareF(KHStrBlack)==0)
			aRgb = KRgbBlack;
		else if(aSource.CompareF(KHStrRed)==0)
			aRgb = KRgbRed;
		else if(aSource.CompareF(KHStrGreen)==0)
			aRgb = KRgbGreen;
		else if(aSource.CompareF(KHStrBlue)==0)
			aRgb = KRgbBlue;
		else if(aSource.CompareF(KHStrYellow)==0)
			aRgb = KRgbYellow;
		else if(aSource.CompareF(KHStrMagenta)==0)
			aRgb = KRgbMagenta;
		else if(aSource.CompareF(KHStrCyan)==0)
			aRgb = KRgbCyan;
		else if(aSource.CompareF(KHStrGray)==0)
			aRgb = KRgbGray;
		else if(aSource.CompareF(KHStrWhite)==0)
			aRgb = KRgbWhite;
		else
			aRgb = KRgbBlack;
	}
}

void UIControlUtil::StringReplace(const TDesC& aSource, const TDesC& aTarget, const TDesC& aReplacement, TDes& aDest)
{
	aDest.Zero();
	TInt pos1 = 0, pos2 = 0;
	do
	{
		pos2 = aSource.Mid(pos1).Find(aTarget);
		if(pos2==KErrNotFound)
		{
			aDest.Append(aSource.Mid(pos1));
			break;
		}
		aDest.Append(aSource.Mid(pos1, pos2));
		aDest.Append(aReplacement);
		pos1 = pos1 + pos2 + aTarget.Length();
	}while(ETrue);
}

void UIControlUtil::StringReplace(TDes& aTarget, TChar aSrcChar, TChar aDestChar)
{
	TInt pos1 = 0, pos2 = 0;
	while(pos1<aTarget.Length()
		&& (pos2=aTarget.Mid(pos1).Locate(aSrcChar))!=KErrNotFound) 
	{
		pos2 += pos1;
		if(aDestChar!=0) 
		{
			aTarget[pos2] = aDestChar;
			pos1 = pos2 + 1;
		}
		else 
		{
			aTarget.Delete(pos2, 1);
			pos1 = pos2;
		}	
	}
}
